library(tidyverse)
library(janitor)
library(here)
local_authority_only_data <- read_csv(here::here("data/clean_data/gb_local_authority_walk_dist_percent_shs.csv")) %>% clean_names()
── Column specification ────────────────────────────────────────────────────────────────────────────────
cols(
year = col_double(),
local_authority = col_character(),
less_than_11_mins = col_double(),
an_11_minute_walk_or_more = col_double(),
a_5_minute_walk_or_less = col_double(),
within_a_6_10_minute_walk = col_double(),
dont_know = col_double()
)
all_walk_dist_categories <-
read_csv(here::here("data/clean_data/gb_walk_dist_long_pivot_shs.csv")) %>% clean_names()
── Column specification ────────────────────────────────────────────────────────────────────────────────
cols(
year = col_double(),
local_authority = col_character(),
type = col_character(),
class = col_character(),
less_than_11_mins = col_double(),
an_11_minute_walk_or_more = col_double(),
a_5_minute_walk_or_less = col_double(),
within_a_6_10_minute_walk = col_double(),
dont_know = col_double()
)
BQ: 1. Are there certain groups that have local access to green space?
DQ: 1. Are there certain groups, more than others, who report having access to green or blue spaces within 10 minutes of their homes.
BQ: 2. Are there groups that are lacking access?
DQ: 2. Are there certain groups, more than others, who report having access to green or blue spaces further than 10 minutes away from their homes.
First, we will take a broad overview of the population of Scotland and isolate whether there are any particular groups that had a high percentage of respondents reporting having green or blue space within 10 minutes of their homes:
all_walk_dist_categories %>%
filter(local_authority == "Scotland")
all_walk_dist_categories %>%
filter(local_authority != "Scotland") %>%
group_by(type, class) %>%
summarise(mean = round(mean(less_than_11_mins))) %>%
arrange(desc(mean))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
all_means_scot_groups_less_11 <-
all_walk_dist_categories %>%
filter(local_authority == "Scotland") %>%
group_by(type, class) %>%
summarise(mean = round(mean(less_than_11_mins))) %>%
arrange(desc(mean))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
all_means_scot_groups_less_11
all_cats_2019 <-
all_walk_dist_categories %>%
filter(local_authority == "Scotland",
year == "2019") %>%
group_by(type, class) %>%
summarise(less_than_11_mins) %>%
arrange(desc(less_than_11_mins))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
Means has been taken across the two different data frames. The first shows the average for different groups across the available years (2013 - 2019) based on all percentages reported individually by local_authorities. The second shows averages for different groups across the same years but with percentages reported for Scotland in total. Given that the totals for both datasets were originally provided in round numbers, the means have also been rounded.
Also, given that there are a number of gaps in the regional datasets for certain groups across the years, it has been concluded that the overall Scotland-wide figures would be more robust in terms of analysis. This is especially the case for classes such as “Non-White_Ethnicity” and “Other Tenures”, which in the case of the former we only have Scottish and Glasgow-wide percentages and in the case of the latter only Scotland.
The level of significance that can be drawn from such data is questionable. Firstly, the walking time-distance categories are very much estimates. It is interesting to consider other real-world and hypothetical ways in which estimates such as these could be made more accurate, including using more precise census data and/or polygon map analyses to more adequately measure the distance from an individuals home to a place of green space. In the case of the former, confidentiality issues would more than like raise they’re head. In the case of the former, it is almost certain that a large degree on granularity in terms of individuals personally characteristics would be lost, especially in terms of more built up urban areas with multiple occupants in high rises. Finally, there is actually a large argument to suggest that accuracy in terms of home to green space measurements is not the key attribute to be focussed in on.
However, it is my understanding that the impact of green space is being explored mainly as a force for the improvement of individuals mental, as well as physical, well-being. With this in mind, it seems entirely appropriate that it is a subjective estimate being explored which suggests the psychological rather than exact physical distance of green spaces to individual homes. Using a categorical estimate actually adds a great deal of subjective relevance to the measures, rather than drawing away from them. A ninety year old with a zimmer-frame may have a very different understanding of a 10-minute walk when compared to an 18 year-old. The estimate also gets us over the tricky issue of what access actually means. When using an estimate, access is quickly defined as what people themselves feel is available to them which ultimately dictates whether they make use of any real or perceived access.
#To clarify, this is a graph for the whole of Scotland showing the mean values across from 2013 to 2019.
all_means_scot_groups_less_11 %>%
ggplot() +
aes(x = mean, y = class, fill = type) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

NA
#And this shows just 2019 figures, once again just for Scotland
all_cats_2019 %>%
ggplot() +
aes(x = less_than_11_mins, y = class, fill = type) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

With all these caveats in mind, looking at our data we see relatively high levels across the different groups. Nominally, the groups with the largest mean percentage were individuals with children and individuals who a mortgage or other substantial domestic loan. The margins between all the different categories are fairly marginal and therefore it makes it relatively difficult to say that for example males are, in general, more likely to live within 10 minutes of a green space when compared to the 80% least deprived in the population, with only 1 percentage point between them. However, what their does appear to be is some clear differences within the different type categories:
What follows is a breakdown of these different types, which is hoped will shed further light on the question at hand.
all_means_scot_groups_less_11 %>%
distinct(type)
all_means_scot_groups_less_11 %>%
filter(type == "age") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "ethnicity") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "gender") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "household_type") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "simd_quintiles") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "type_of_tenure") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

all_means_scot_groups_less_11 %>%
filter(type == "urban_rural_classification") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

Looking at these graphs, the following conclusions spring to mind which require further analysis:
- It looks like there is a sustained gap between people with a mortgage and other types of tenure. This is quite curios, especially considering one of these alternative groups is owned outright. Equally, it appears that individuals who reported having an other form of tenure apart from those provided were less likely to have local access.
- Although there is a gap between the two SIMD groups, this is perhaps not as large as I would have expected. 3. Pensioners seem to lag behind other household groups.
- Males report closer access, but not by a large margin.
- 65 year-olds and older seem to lag to a significant level behind other age groups.
- Perhaps most strikingly of all, those of White ethnicity are far more likely to report having local access to green space when compared to all other individuals of Non-White Ethnicity.
Now that we have some conclusions that may answer our first two questions, I’d like to move on and address the regional element within the brief and in turn perhaps partly answer question 4 namely:
BQ & DQ 4: Are there any differences between rural and urban areas?
So to begin with, it looks like urban areas only slightly lag behind rural areas. This is in itself quite interesting as I would expect this to be the variable that had the largest effect on access to green space. For a bit more illumination on the matter, I think it would be good to take a look at the regional figures. Firstly, let’s look at the levels of access across all groups, but split by region.
local_means <-
local_authority_only_data %>%
group_by(local_authority) %>%
summarise(less_6_mean = round(mean(a_5_minute_walk_or_less)),
less_11_mean = round(mean(less_than_11_mins)),
plus_11_mean = round(mean(an_11_minute_walk_or_more))) %>%
arrange(desc(less_11_mean))
`summarise()` ungrouping output (override with `.groups` argument)
local_means
local_means %>%
ggplot() +
aes(x = less_11_mean, y = local_authority) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

So this ends up throwing up some genuinely interesting and surprising figures. Who, for example, would think that on average an individual living in the City of Edinburgh would be almost ten percentage points more likely to report having local access to green space when compared to someone from Orkney!! Now it seems like we can see why the Urban vs Rural divide is not as large as would have first been anticipated. Like the groups addressed earlier, it seems that in general a vast majority of people live with local access to green spaces as I have defined it.
What could be interesting is to see what sort of change in figures we get if this definition is adjusted. Equally, it would be be informative to start combining the local_authority data with the groups. Although not all combinations will have data available, it will be interested to compare these nonetheless.
Definition Adjusted - Within 5 minutes.
This change definetely has president. Investigating a little further, it seems that a couple of government sources referencing access to green space actually use a 5 minute walk or less as their definition ref1 , [ref2] (https://nationalperformance.gov.scot/measuring-progress/national-indicator-performance).
So, with this in mind, let’s run the above analysis again with the adjusted definition:
#First, creating a data frame with means of all the different groups from 2013-2019 for the whole of Scotland.
minus_5_all_means_scot_groups <-
all_walk_dist_categories %>%
filter(local_authority == "Scotland") %>%
group_by(type, class) %>%
summarise(mean = round(mean(a_5_minute_walk_or_less))) %>%
arrange(desc(mean))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
minus_5_all_means_scot_groups
minus_5_all_cats_2019 <-
all_walk_dist_categories %>%
filter(local_authority == "Scotland",
year == "2019") %>%
group_by(type, class) %>%
summarise(a_5_minute_walk_or_less) %>%
arrange(desc(a_5_minute_walk_or_less))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
minus_5_all_cats_2019
minus_5_all_means_scot_groups %>%
ggplot() +
aes(x = mean, y = class, fill = type) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_cats_2019 %>%
ggplot() +
aes(x = a_5_minute_walk_or_less, y = class, fill = type) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "age") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "ethnicity") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "gender") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "household_type") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "simd_quintiles") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "type_of_tenure") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

minus_5_all_means_scot_groups %>%
filter(type == "urban_rural_classification") %>%
ggplot() +
aes(x = mean, y = class, fill = class) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

A quick note: Among the national performance documentation, there are some more excellent definitions and criteria for change noted:
Definitions:
Adults are people resident in Scotland aged over 16.
Green and Blue Space is described in the Scottish Household Survey as comprising ‘public green or open spaces in your local area, for example a park, countryside, wood, play area, canal path, riverside or beach’.
Criteria for Change:
Any difference in the percentage within +/- 2 percentage points of last year’s figure suggests that the position is more likely to be maintaining than showing any change. An increase of 2 percentage points or more suggests the position is improving. A decrease of 2 percentage points or more suggests the position is worsening. The threshold of 2 percentage points chosen is based on the data currently, and may be reviewed as more data points become available
With the above +/- 2 percentage point criteria in mind, I would suggest that the same measure could also be used as a criteria for significance . In other words, if there is a difference of +/- 2 percentage points between one group and another, then it is deemed that one class in a type is more likely/less likely than another to have access to green/blue space.
Looking at a lot of these graphs, it looks like many of the patterns within and between categories have been intensified, whilst others have changed to a significant degree.
- The gap between those who have a mortgage/other domestic loan and other tenure groups has been maintained. Interestingly, the Social Renting group has dropped below the group Other Tenure. The percentage point gap between mortgage and social renting group was nine points.
- The gap between the two SIMD groups has widened significantly. In the 10 or less analysis, it was 4 percentage points. In 5 or less, it is 8 points.
- Pensioners once again lagged behind adults with and without children.
- Males once again report closer access, with the margin growing only slightly from 2 percentage points to 3.
- The gap between 65-year-olds+ was maintained.
- Once again, the headline figure is that the gap in local access between white and non-white ethnicity has been further widened with a gap of 13 percentage points, up from 8. Those classed as non-white ethnicity had the lowest percentage of any group addressed over the last 7 years period looked into, with only 54% having access to green or blue space within 5 minutes walk of there house. This should be put into context by highlighting the definition again.
Generate means for all walking distances.
all_walk_dist_means_scot_groups <-
all_walk_dist_categories %>%
filter(local_authority == "Scotland") %>%
group_by(type, class) %>%
summarise(less_6_mean = round(mean(a_5_minute_walk_or_less)),
less_11_mean = round(mean(less_than_11_mins)),
plus_11_mean = round(mean(an_11_minute_walk_or_more))) %>%
arrange(desc(less_6_mean))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
all_walk_dist_means_scot_groups
all_walk_dist_means_scot_groups %>%
filter(type == "urban_rural_classification")
Another striking insight from the change in definition is the significant change in the urban/rural split. In the less than 11 mean, we had only a slight 1 point difference between the two groups. Yet, once we look at 5 mins of less, we see the gap increase to 12 percentage points in favor of those in a rural setting.
It would be interesting to double-check what the definition used is for rural/urban in the survey or whether this is once again just a subjective response.
**Looks like there is a good source for this created and published in 2016 ref3. I think that it is the 2-fold classification currently being used, This states the the rural classification starts with “Areas with a population of less than 3,000 people, and within a drive time of 30 minutes to a Settlement of 10,000 or more”.
Now, let’s have a look at regional figures again, this time for less than 5 minutes walk:
local_means %>%
ggplot() +
aes(x = less_6_mean, y = local_authority) +
geom_col() +
scale_x_continuous(breaks = seq(from = 0, to = 100, by = 10))

#Could do some sort of plus/minus visualization based on Scotland for these types of graphs.
local_means %>%
arrange(desc(less_6_mean))
- Are there big differences in how far people have to walk to access their green space?
Is the data on the overall sample very skewed towards one out of the three categories or is it relatively evenly dispersed amongst small, medium and long walks to green spaces.
Are similar skews replicated across different regions or are they consistent with the national average.
Back to the graphs that we want to have to illustrate and tell the stories that we’ve found. Let’s start with the Scotland means as the zero point for the less than 5 and, maybe, less that 10 percentages. Let’s put a hover on this one as well.
local_means_plus_minus_scot <-
local_means %>%
mutate(pl_min_less_6 = less_6_mean - less_6_mean[local_authority == "Scotland"],
pl_min_less_11 = less_11_mean - less_11_mean[local_authority == "Scotland"],
pl_min_plus_11 = plus_11_mean - plus_11_mean[local_authority == "Scotland"],
above_below_less_6 = if_else(pl_min_less_6 < 0, "below", "above"))
local_means_plus_minus_scot <-
local_means_plus_minus_scot %>%
mutate(local_authority = fct_reorder(local_authority, pl_min_less_6))
#Could we do a cheeky bit of normalization here? Like they do in the example.
plus_minus_plot <-
local_means_plus_minus_scot %>%
ggplot(aes(x = local_authority, y = pl_min_less_6, label = local_authority)) +
geom_bar(stat = 'identity', aes(fill = above_below_less_6), width = .5) +
scale_fill_manual(name = "Mean Percentage",
labels = c("Above Scotland", "Below Scotland"),
values = c("above" = "#00ba38", "below"= "#f8766d")) +
labs(title = "Percentage of Population Within a 5-minute Walk of Green Space",
subtitle = "Mean figures between 2013 - 2019") +
coord_flip()
plus_minus_plot

ggplotly(plus_minus_plot)
local_means
#These are larger joint boards for electoral registration and the purposes of property valuation for assessing council tax and rates. Seems suitable if we're looking at tenure types.
regions_added_all_walks <-
all_walk_dist_categories %>%
mutate(electoral_region = case_when(local_authority %in% c("East Ayrshire", "North Ayrshire", "South Ayrshire") ~ "Ayrshire",
local_authority %in% c("Scottish Borders") ~ "Borders",
local_authority %in% c("Clackmannanshire", "Falkirk", "Stirling") ~ "Central Scotland",
local_authority %in% c("Dumfries and Galloway") ~ "Dumfries and Galloway",
local_authority %in% c("Argyll and Bute", "East Dunbartonshire", "West Dunbartonshire") ~ "Dunbartonshire and Argyll & Bute",
local_authority %in% c("Fife") ~ "Fife",
local_authority %in% c("Aberdeen City", "Aberdeenshire", "Moray") ~ "Grampian",
local_authority %in% c("Glasgow City") ~ "Glasgow",
local_authority %in% c("Highland", "Na h-Eileanan Siar") ~ "Highlands and Western Isles",
local_authority %in% c("North Lanarkshire", "South Lanarkshire") ~ "Lanarkshire",
local_authority %in% c("East Lothian", "City of Edinburgh", "Midlothian", "West Lothian") ~ "Lothian",
local_authority %in% c("Orkney Islands", "Shetland Islands") ~ "Orkney and Shetland",
local_authority %in% c("East Renfrewshire", "Inverclyde", "Renfrewshire") ~ "Renfrewshire",
local_authority %in% c("Scotland") ~ "Scotland",
local_authority %in% c("Angus", "Dundee City", "Perth and Kinross") ~ "Tayside"
)
)
local_means_plus_minus_scot %>%
grou
Error in grou(.) : could not find function "grou"
Now to decide exactly what to do with tender considering what we’ve just added.
Think I’m going to do a replicate of the above graph but this time for the electoral regions.
regions_added_all_walks %>%
distinct(type)
regions_distances_pivot_long %>%
filter(local_authority == "Scotland",
type == "type_of_tenure",
walking_distance %in% c("a_5_minute_walk_or_less", "within_a_6_10_minute_walk", "an_11_minute_walk_or_more", "dont_know")) %>%
ggplot(aes(x = year, y = values, fill = walking_distance)) +
geom_area() +
facet_wrap(~ class)

That seems like something we could use if all else fails.
regions_distances_pivot_long %>%
distinct(walking_distance)
Thinking now to look into a city by city comparison of certain areas, with some Dundee centric stuff in their as you’d expect!
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoaGVyZSkKCmBgYAoKYGBge3J9CmxvY2FsX2F1dGhvcml0eV9vbmx5X2RhdGEgPC0gcmVhZF9jc3YoaGVyZTo6aGVyZSgiZGF0YS9jbGVhbl9kYXRhL2diX2xvY2FsX2F1dGhvcml0eV93YWxrX2Rpc3RfcGVyY2VudF9zaHMuY3N2IikpICU+JSBjbGVhbl9uYW1lcygpCgphbGxfd2Fsa19kaXN0X2NhdGVnb3JpZXMgPC0KcmVhZF9jc3YoaGVyZTo6aGVyZSgiZGF0YS9jbGVhbl9kYXRhL2diX3dhbGtfZGlzdF9sb25nX3Bpdm90X3Nocy5jc3YiKSkgJT4lIGNsZWFuX25hbWVzKCkKYGBgCgpCUTogMS4gQXJlIHRoZXJlIGNlcnRhaW4gZ3JvdXBzIHRoYXQgaGF2ZSBsb2NhbCBhY2Nlc3MgdG8gZ3JlZW4gc3BhY2U/CgpEUTogMS4gKkFyZSB0aGVyZSBjZXJ0YWluIGdyb3VwcywgbW9yZSB0aGFuIG90aGVycywgd2hvIHJlcG9ydCBoYXZpbmcgYWNjZXNzIHRvIGdyZWVuIG9yIGJsdWUgc3BhY2VzIHdpdGhpbiAxMCBtaW51dGVzIG9mIHRoZWlyIGhvbWVzLioKCkJROiAyLiBBcmUgdGhlcmUgZ3JvdXBzIHRoYXQgYXJlIGxhY2tpbmcgYWNjZXNzPwoKRFE6IDIuICpBcmUgdGhlcmUgY2VydGFpbiBncm91cHMsIG1vcmUgdGhhbiBvdGhlcnMsIHdobyByZXBvcnQgaGF2aW5nIGFjY2VzcyB0byBncmVlbiBvciBibHVlIHNwYWNlcyBmdXJ0aGVyIHRoYW4gMTAgbWludXRlcyBhd2F5IGZyb20gdGhlaXIgaG9tZXMuKgoKCkZpcnN0LCB3ZSB3aWxsIHRha2UgYSBicm9hZCBvdmVydmlldyBvZiB0aGUgcG9wdWxhdGlvbiBvZiBTY290bGFuZCBhbmQgaXNvbGF0ZSB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgcGFydGljdWxhciBncm91cHMgdGhhdCBoYWQgYSBoaWdoIHBlcmNlbnRhZ2Ugb2YgcmVzcG9uZGVudHMgcmVwb3J0aW5nIGhhdmluZyBncmVlbiBvciBibHVlIHNwYWNlIHdpdGhpbiAxMCBtaW51dGVzIG9mIHRoZWlyIGhvbWVzOgoKYGBge3J9CmFsbF93YWxrX2Rpc3RfY2F0ZWdvcmllcyAlPiUgCiAgZmlsdGVyKGxvY2FsX2F1dGhvcml0eSA9PSAiU2NvdGxhbmQiKQpgYGAKCgpgYGB7cn0KYWxsX3dhbGtfZGlzdF9jYXRlZ29yaWVzICU+JSAKICBmaWx0ZXIobG9jYWxfYXV0aG9yaXR5ICE9ICJTY290bGFuZCIpICU+JSAKICBncm91cF9ieSh0eXBlLCBjbGFzcykgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gcm91bmQobWVhbihsZXNzX3RoYW5fMTFfbWlucykpKSAlPiUgCiAgYXJyYW5nZShkZXNjKG1lYW4pKQoKYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEgPC0KYWxsX3dhbGtfZGlzdF9jYXRlZ29yaWVzICU+JSAKICBmaWx0ZXIobG9jYWxfYXV0aG9yaXR5ID09ICJTY290bGFuZCIpICU+JSAKICBncm91cF9ieSh0eXBlLCBjbGFzcykgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gcm91bmQobWVhbihsZXNzX3RoYW5fMTFfbWlucykpKSAlPiUgCiAgYXJyYW5nZShkZXNjKG1lYW4pKQoKYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEKYGBgCgpgYGB7cn0KYWxsX2NhdHNfMjAxOSA8LQphbGxfd2Fsa19kaXN0X2NhdGVnb3JpZXMgJT4lIAogIGZpbHRlcihsb2NhbF9hdXRob3JpdHkgPT0gIlNjb3RsYW5kIiwKICAgICAgICAgeWVhciA9PSAiMjAxOSIpICU+JSAKICBncm91cF9ieSh0eXBlLCBjbGFzcykgJT4lIAogIHN1bW1hcmlzZShsZXNzX3RoYW5fMTFfbWlucykgJT4lIAogIGFycmFuZ2UoZGVzYyhsZXNzX3RoYW5fMTFfbWlucykpCmBgYAoKKipNZWFucyBoYXMgYmVlbiB0YWtlbiBhY3Jvc3MgdGhlIHR3byBkaWZmZXJlbnQgZGF0YSBmcmFtZXMuIFRoZSBmaXJzdCBzaG93cyB0aGUgYXZlcmFnZSBmb3IgZGlmZmVyZW50IGdyb3VwcyBhY3Jvc3MgdGhlIGF2YWlsYWJsZSB5ZWFycyAoMjAxMyAtIDIwMTkpIGJhc2VkIG9uIGFsbCBwZXJjZW50YWdlcyByZXBvcnRlZCBpbmRpdmlkdWFsbHkgYnkgbG9jYWxfYXV0aG9yaXRpZXMuIFRoZSBzZWNvbmQgc2hvd3MgYXZlcmFnZXMgZm9yIGRpZmZlcmVudCBncm91cHMgYWNyb3NzIHRoZSBzYW1lIHllYXJzIGJ1dCB3aXRoIHBlcmNlbnRhZ2VzIHJlcG9ydGVkIGZvciBTY290bGFuZCBpbiB0b3RhbC4gR2l2ZW4gdGhhdCB0aGUgdG90YWxzIGZvciBib3RoIGRhdGFzZXRzIHdlcmUgb3JpZ2luYWxseSBwcm92aWRlZCBpbiByb3VuZCBudW1iZXJzLCB0aGUgbWVhbnMgaGF2ZSBhbHNvIGJlZW4gcm91bmRlZC4qKgoKQWxzbywgZ2l2ZW4gdGhhdCB0aGVyZSBhcmUgYSBudW1iZXIgb2YgZ2FwcyBpbiB0aGUgcmVnaW9uYWwgZGF0YXNldHMgZm9yIGNlcnRhaW4gZ3JvdXBzIGFjcm9zcyB0aGUgeWVhcnMsIGl0IGhhcyBiZWVuIGNvbmNsdWRlZCB0aGF0IHRoZSBvdmVyYWxsIFNjb3RsYW5kLXdpZGUgZmlndXJlcyB3b3VsZCBiZSBtb3JlIHJvYnVzdCBpbiB0ZXJtcyBvZiBhbmFseXNpcy4gVGhpcyBpcyBlc3BlY2lhbGx5IHRoZSBjYXNlIGZvciBjbGFzc2VzIHN1Y2ggYXMgIk5vbi1XaGl0ZV9FdGhuaWNpdHkiIGFuZCAiT3RoZXIgVGVudXJlcyIsIHdoaWNoIGluIHRoZSBjYXNlIG9mIHRoZSBmb3JtZXIgd2Ugb25seSBoYXZlIFNjb3R0aXNoIGFuZCBHbGFzZ293LXdpZGUgcGVyY2VudGFnZXMgYW5kIGluIHRoZSBjYXNlIG9mIHRoZSBsYXR0ZXIgb25seSBTY290bGFuZC4gCgpUaGUgbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlIHRoYXQgY2FuIGJlIGRyYXduIGZyb20gc3VjaCBkYXRhIGlzIHF1ZXN0aW9uYWJsZS4gRmlyc3RseSwgdGhlIHdhbGtpbmcgdGltZS1kaXN0YW5jZSBjYXRlZ29yaWVzIGFyZSB2ZXJ5IG11Y2ggZXN0aW1hdGVzLiBJdCBpcyBpbnRlcmVzdGluZyB0byBjb25zaWRlciBvdGhlciByZWFsLXdvcmxkIGFuZCBoeXBvdGhldGljYWwgd2F5cyBpbiB3aGljaCBlc3RpbWF0ZXMgc3VjaCBhcyB0aGVzZSBjb3VsZCBiZSBtYWRlIG1vcmUgYWNjdXJhdGUsIGluY2x1ZGluZyB1c2luZyBtb3JlIHByZWNpc2UgY2Vuc3VzIGRhdGEgYW5kL29yIHBvbHlnb24gbWFwIGFuYWx5c2VzIHRvIG1vcmUgYWRlcXVhdGVseSBtZWFzdXJlIHRoZSBkaXN0YW5jZSBmcm9tIGFuIGluZGl2aWR1YWxzIGhvbWUgdG8gYSBwbGFjZSBvZiBncmVlbiBzcGFjZS4gSW4gdGhlIGNhc2Ugb2YgdGhlIGZvcm1lciwgY29uZmlkZW50aWFsaXR5IGlzc3VlcyB3b3VsZCBtb3JlIHRoYW4gbGlrZSByYWlzZSB0aGV5J3JlIGhlYWQuIEluIHRoZSBjYXNlIG9mIHRoZSBmb3JtZXIsIGl0IGlzIGFsbW9zdCBjZXJ0YWluIHRoYXQgYSBsYXJnZSBkZWdyZWUgb24gZ3JhbnVsYXJpdHkgaW4gdGVybXMgb2YgaW5kaXZpZHVhbHMgcGVyc29uYWxseSBjaGFyYWN0ZXJpc3RpY3Mgd291bGQgYmUgbG9zdCwgZXNwZWNpYWxseSBpbiB0ZXJtcyBvZiBtb3JlIGJ1aWx0IHVwIHVyYmFuIGFyZWFzIHdpdGggbXVsdGlwbGUgb2NjdXBhbnRzIGluIGhpZ2ggcmlzZXMuIEZpbmFsbHksIHRoZXJlIGlzIGFjdHVhbGx5IGEgbGFyZ2UgYXJndW1lbnQgdG8gc3VnZ2VzdCB0aGF0IGFjY3VyYWN5IGluIHRlcm1zIG9mIGhvbWUgdG8gZ3JlZW4gc3BhY2UgbWVhc3VyZW1lbnRzIGlzIG5vdCB0aGUga2V5IGF0dHJpYnV0ZSB0byBiZSBmb2N1c3NlZCBpbiBvbi4gCgpIb3dldmVyLCBpdCBpcyBteSB1bmRlcnN0YW5kaW5nIHRoYXQgdGhlIGltcGFjdCBvZiBncmVlbiBzcGFjZSBpcyBiZWluZyBleHBsb3JlZCBtYWlubHkgYXMgYSBmb3JjZSBmb3IgdGhlIGltcHJvdmVtZW50IG9mIGluZGl2aWR1YWxzIG1lbnRhbCwgYXMgd2VsbCBhcyBwaHlzaWNhbCwgd2VsbC1iZWluZy4gV2l0aCB0aGlzIGluIG1pbmQsIGl0IHNlZW1zIGVudGlyZWx5IGFwcHJvcHJpYXRlIHRoYXQgaXQgaXMgYSBzdWJqZWN0aXZlIGVzdGltYXRlIGJlaW5nIGV4cGxvcmVkIHdoaWNoIHN1Z2dlc3RzIHRoZSBwc3ljaG9sb2dpY2FsIHJhdGhlciB0aGFuIGV4YWN0IHBoeXNpY2FsIGRpc3RhbmNlIG9mIGdyZWVuIHNwYWNlcyB0byBpbmRpdmlkdWFsIGhvbWVzLiBVc2luZyBhIGNhdGVnb3JpY2FsIGVzdGltYXRlIGFjdHVhbGx5IGFkZHMgYSBncmVhdCBkZWFsIG9mIHN1YmplY3RpdmUgcmVsZXZhbmNlIHRvIHRoZSBtZWFzdXJlcywgcmF0aGVyIHRoYW4gZHJhd2luZyBhd2F5IGZyb20gdGhlbS4gQSBuaW5ldHkgeWVhciBvbGQgd2l0aCBhIHppbW1lci1mcmFtZSBtYXkgaGF2ZSBhIHZlcnkgZGlmZmVyZW50IHVuZGVyc3RhbmRpbmcgb2YgYSAxMC1taW51dGUgd2FsayB3aGVuIGNvbXBhcmVkIHRvIGFuIDE4IHllYXItb2xkLiBUaGUgZXN0aW1hdGUgYWxzbyBnZXRzIHVzIG92ZXIgdGhlIHRyaWNreSBpc3N1ZSBvZiB3aGF0IGFjY2VzcyBhY3R1YWxseSBtZWFucy4gV2hlbiB1c2luZyBhbiBlc3RpbWF0ZSwgYWNjZXNzIGlzIHF1aWNrbHkgZGVmaW5lZCBhcyB3aGF0IHBlb3BsZSB0aGVtc2VsdmVzIGZlZWwgaXMgYXZhaWxhYmxlIHRvIHRoZW0gd2hpY2ggdWx0aW1hdGVseSBkaWN0YXRlcyB3aGV0aGVyIHRoZXkgbWFrZSB1c2Ugb2YgYW55IHJlYWwgb3IgcGVyY2VpdmVkIGFjY2Vzcy4gCgoKYGBge3J9CiNUbyBjbGFyaWZ5LCB0aGlzIGlzIGEgZ3JhcGggZm9yIHRoZSB3aG9sZSBvZiBTY290bGFuZCBzaG93aW5nIHRoZSBtZWFuIHZhbHVlcyBhY3Jvc3MgZnJvbSAyMDEzIHRvIDIwMTkuIAphbGxfbWVhbnNfc2NvdF9ncm91cHNfbGVzc18xMSAlPiUKICBnZ3Bsb3QoKSArIAogIGFlcyh4ID0gbWVhbiwgeSA9IGNsYXNzLCBmaWxsID0gdHlwZSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKICAKYGBgCgpgYGB7cn0KI0FuZCB0aGlzIHNob3dzIGp1c3QgMjAxOSBmaWd1cmVzLCBvbmNlIGFnYWluIGp1c3QgZm9yIFNjb3RsYW5kCmFsbF9jYXRzXzIwMTkgJT4lCiAgZ2dwbG90KCkgKyAKICBhZXMoeCA9IGxlc3NfdGhhbl8xMV9taW5zLCB5ID0gY2xhc3MsIGZpbGwgPSB0eXBlKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQoKYGBgCgpXaXRoIGFsbCB0aGVzZSBjYXZlYXRzIGluIG1pbmQsIGxvb2tpbmcgYXQgb3VyIGRhdGEgd2Ugc2VlIHJlbGF0aXZlbHkgaGlnaCBsZXZlbHMgYWNyb3NzIHRoZSBkaWZmZXJlbnQgZ3JvdXBzLiBOb21pbmFsbHksIHRoZSBncm91cHMgd2l0aCB0aGUgbGFyZ2VzdCBtZWFuIHBlcmNlbnRhZ2Ugd2VyZSBpbmRpdmlkdWFscyB3aXRoIGNoaWxkcmVuIGFuZCBpbmRpdmlkdWFscyB3aG8gYSBtb3J0Z2FnZSBvciBvdGhlciBzdWJzdGFudGlhbCBkb21lc3RpYyBsb2FuLiBUaGUgbWFyZ2lucyBiZXR3ZWVuIGFsbCB0aGUgZGlmZmVyZW50IGNhdGVnb3JpZXMgYXJlIGZhaXJseSBtYXJnaW5hbCBhbmQgdGhlcmVmb3JlIGl0IG1ha2VzIGl0IHJlbGF0aXZlbHkgZGlmZmljdWx0IHRvIHNheSB0aGF0IGZvciBleGFtcGxlIG1hbGVzIGFyZSwgaW4gZ2VuZXJhbCwgbW9yZSBsaWtlbHkgdG8gbGl2ZSB3aXRoaW4gMTAgbWludXRlcyBvZiBhIGdyZWVuIHNwYWNlIHdoZW4gY29tcGFyZWQgdG8gdGhlIDgwJSBsZWFzdCBkZXByaXZlZCBpbiB0aGUgcG9wdWxhdGlvbiwgd2l0aCBvbmx5IDEgcGVyY2VudGFnZSBwb2ludCBiZXR3ZWVuIHRoZW0uIEhvd2V2ZXIsIHdoYXQgdGhlaXIgZG9lcyBhcHBlYXIgdG8gYmUgaXMgc29tZSBjbGVhciBkaWZmZXJlbmNlcyB3aXRoaW4gdGhlIGRpZmZlcmVudCB0eXBlIGNhdGVnb3JpZXM6CgpXaGF0IGZvbGxvd3MgaXMgYSBicmVha2Rvd24gb2YgdGhlc2UgZGlmZmVyZW50IHR5cGVzLCB3aGljaCBpcyBob3BlZCB3aWxsIHNoZWQgZnVydGhlciBsaWdodCBvbiB0aGUgcXVlc3Rpb24gYXQgaGFuZC4gCgpgYGB7cn0KYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEgJT4lCiAgZGlzdGluY3QodHlwZSkKYGBgCgoKYGBge3J9CmFsbF9tZWFuc19zY290X2dyb3Vwc19sZXNzXzExICU+JSAKICBmaWx0ZXIodHlwZSA9PSAiYWdlIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQpgYGAKCmBgYHtyfQphbGxfbWVhbnNfc2NvdF9ncm91cHNfbGVzc18xMSAlPiUgCiAgZmlsdGVyKHR5cGUgPT0gImV0aG5pY2l0eSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLCB5ID0gY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKCmBgYAoKYGBge3J9CmFsbF9tZWFuc19zY290X2dyb3Vwc19sZXNzXzExICU+JSAKICBmaWx0ZXIodHlwZSA9PSAiZ2VuZGVyIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQoKYGBgCgpgYGB7cn0KYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEgJT4lIAogIGZpbHRlcih0eXBlID09ICJob3VzZWhvbGRfdHlwZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLCB5ID0gY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCgpgYGB7cn0KYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEgJT4lIAogIGZpbHRlcih0eXBlID09ICJzaW1kX3F1aW50aWxlcyIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLCB5ID0gY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCgpgYGB7cn0KYWxsX21lYW5zX3Njb3RfZ3JvdXBzX2xlc3NfMTEgJT4lIAogIGZpbHRlcih0eXBlID09ICJ0eXBlX29mX3RlbnVyZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLCB5ID0gY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKCmBgYAoKYGBge3J9CmFsbF9tZWFuc19zY290X2dyb3Vwc19sZXNzXzExICU+JSAKICBmaWx0ZXIodHlwZSA9PSAidXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24iKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbWVhbiwgeSA9IGNsYXNzLCBmaWxsID0gY2xhc3MpICsKICBnZW9tX2NvbCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDEwMCwgYnkgPSAxMCkpCmBgYAoKTG9va2luZyBhdCB0aGVzZSBncmFwaHMsIHRoZSBmb2xsb3dpbmcgY29uY2x1c2lvbnMgc3ByaW5nIHRvIG1pbmQgd2hpY2ggcmVxdWlyZSBmdXJ0aGVyIGFuYWx5c2lzOgoKMS4gSXQgbG9va3MgbGlrZSB0aGVyZSBpcyBhIHN1c3RhaW5lZCBnYXAgYmV0d2VlbiBwZW9wbGUgd2l0aCBhIG1vcnRnYWdlIGFuZCBvdGhlciB0eXBlcyBvZiB0ZW51cmUuIFRoaXMgaXMgcXVpdGUgY3VyaW9zLCBlc3BlY2lhbGx5IGNvbnNpZGVyaW5nIG9uZSBvZiB0aGVzZSBhbHRlcm5hdGl2ZSBncm91cHMgaXMgb3duZWQgb3V0cmlnaHQuIEVxdWFsbHksIGl0IGFwcGVhcnMgdGhhdCBpbmRpdmlkdWFscyB3aG8gcmVwb3J0ZWQgaGF2aW5nIGFuIG90aGVyIGZvcm0gb2YgdGVudXJlIGFwYXJ0IGZyb20gdGhvc2UgcHJvdmlkZWQgd2VyZSBsZXNzIGxpa2VseSB0byBoYXZlIGxvY2FsIGFjY2Vzcy4gCjIuIEFsdGhvdWdoIHRoZXJlIGlzIGEgZ2FwIGJldHdlZW4gdGhlIHR3byBTSU1EIGdyb3VwcywgdGhpcyBpcyBwZXJoYXBzIG5vdCBhcyBsYXJnZSBhcyBJIHdvdWxkIGhhdmUgZXhwZWN0ZWQuIDMuIFBlbnNpb25lcnMgc2VlbSB0byBsYWcgYmVoaW5kIG90aGVyIGhvdXNlaG9sZCBncm91cHMuIAo0LiBNYWxlcyByZXBvcnQgY2xvc2VyIGFjY2VzcywgYnV0IG5vdCBieSBhIGxhcmdlIG1hcmdpbi4gCjUuIDY1IHllYXItb2xkcyBhbmQgb2xkZXIgc2VlbSB0byBsYWcgdG8gYSBzaWduaWZpY2FudCBsZXZlbCBiZWhpbmQgb3RoZXIgYWdlIGdyb3Vwcy4KNi4gUGVyaGFwcyBtb3N0IHN0cmlraW5nbHkgb2YgYWxsLCB0aG9zZSBvZiBXaGl0ZSBldGhuaWNpdHkgYXJlIGZhciBtb3JlIGxpa2VseSB0byByZXBvcnQgaGF2aW5nIGxvY2FsIGFjY2VzcyB0byBncmVlbiBzcGFjZSB3aGVuIGNvbXBhcmVkIHRvIGFsbCBvdGhlciBpbmRpdmlkdWFscyBvZiBOb24tV2hpdGUgRXRobmljaXR5LgoKTm93IHRoYXQgd2UgaGF2ZSBzb21lIGNvbmNsdXNpb25zIHRoYXQgbWF5IGFuc3dlciBvdXIgZmlyc3QgdHdvIHF1ZXN0aW9ucywgSSdkIGxpa2UgdG8gbW92ZSBvbiBhbmQgYWRkcmVzcyB0aGUgcmVnaW9uYWwgZWxlbWVudCB3aXRoaW4gdGhlIGJyaWVmIGFuZCBpbiB0dXJuIHBlcmhhcHMgcGFydGx5IGFuc3dlciBxdWVzdGlvbiA0IG5hbWVseToKCkJRICYgRFEgNDogKkFyZSB0aGVyZSBhbnkgZGlmZmVyZW5jZXMgYmV0d2VlbiBydXJhbCBhbmQgdXJiYW4gYXJlYXM/KgoKU28gdG8gYmVnaW4gd2l0aCwgaXQgbG9va3MgbGlrZSB1cmJhbiBhcmVhcyBvbmx5IHNsaWdodGx5IGxhZyBiZWhpbmQgcnVyYWwgYXJlYXMuIFRoaXMgaXMgaW4gaXRzZWxmIHF1aXRlIGludGVyZXN0aW5nIGFzIEkgd291bGQgZXhwZWN0IHRoaXMgdG8gYmUgdGhlIHZhcmlhYmxlIHRoYXQgaGFkIHRoZSBsYXJnZXN0IGVmZmVjdCBvbiBhY2Nlc3MgdG8gZ3JlZW4gc3BhY2UuIEZvciBhIGJpdCBtb3JlIGlsbHVtaW5hdGlvbiBvbiB0aGUgbWF0dGVyLCBJIHRoaW5rIGl0IHdvdWxkIGJlIGdvb2QgdG8gdGFrZSBhIGxvb2sgYXQgdGhlIHJlZ2lvbmFsIGZpZ3VyZXMuIEZpcnN0bHksIGxldCdzIGxvb2sgYXQgdGhlIGxldmVscyBvZiBhY2Nlc3MgYWNyb3NzIGFsbCBncm91cHMsIGJ1dCBzcGxpdCBieSByZWdpb24uCgpgYGB7cn0KCmxvY2FsX21lYW5zIDwtCmxvY2FsX2F1dGhvcml0eV9vbmx5X2RhdGEgJT4lIAogIGdyb3VwX2J5KGxvY2FsX2F1dGhvcml0eSkgJT4lIAogIHN1bW1hcmlzZShsZXNzXzZfbWVhbiA9IHJvdW5kKG1lYW4oYV81X21pbnV0ZV93YWxrX29yX2xlc3MpKSwKICAgICAgICAgICAgbGVzc18xMV9tZWFuID0gcm91bmQobWVhbihsZXNzX3RoYW5fMTFfbWlucykpLAogICAgICAgICAgICBwbHVzXzExX21lYW4gPSByb3VuZChtZWFuKGFuXzExX21pbnV0ZV93YWxrX29yX21vcmUpKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhsZXNzXzExX21lYW4pKQoKbG9jYWxfbWVhbnMKYGBgCgpgYGB7cn0KCmxvY2FsX21lYW5zICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBsZXNzXzExX21lYW4sIHkgPSBsb2NhbF9hdXRob3JpdHkpICsKICBnZW9tX2NvbCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDEwMCwgYnkgPSAxMCkpCmBgYAoKU28gdGhpcyBlbmRzIHVwIHRocm93aW5nIHVwIHNvbWUgZ2VudWluZWx5IGludGVyZXN0aW5nIGFuZCBzdXJwcmlzaW5nIGZpZ3VyZXMuIFdobywgZm9yIGV4YW1wbGUsIHdvdWxkIHRoaW5rIHRoYXQgb24gYXZlcmFnZSBhbiBpbmRpdmlkdWFsIGxpdmluZyBpbiB0aGUgQ2l0eSBvZiBFZGluYnVyZ2ggd291bGQgYmUgYWxtb3N0IHRlbiBwZXJjZW50YWdlIHBvaW50cyBtb3JlIGxpa2VseSB0byByZXBvcnQgaGF2aW5nIGxvY2FsIGFjY2VzcyB0byBncmVlbiBzcGFjZSB3aGVuIGNvbXBhcmVkIHRvIHNvbWVvbmUgZnJvbSBPcmtuZXkhISBOb3cgaXQgc2VlbXMgbGlrZSB3ZSBjYW4gc2VlIHdoeSB0aGUgVXJiYW4gdnMgUnVyYWwgZGl2aWRlIGlzIG5vdCBhcyBsYXJnZSBhcyB3b3VsZCBoYXZlIGZpcnN0IGJlZW4gYW50aWNpcGF0ZWQuIExpa2UgdGhlIGdyb3VwcyBhZGRyZXNzZWQgZWFybGllciwgaXQgc2VlbXMgdGhhdCBpbiBnZW5lcmFsIGEgdmFzdCBtYWpvcml0eSBvZiBwZW9wbGUgbGl2ZSB3aXRoIGxvY2FsIGFjY2VzcyB0byBncmVlbiBzcGFjZXMgYXMgSSBoYXZlIGRlZmluZWQgaXQuIAoKV2hhdCBjb3VsZCBiZSBpbnRlcmVzdGluZyBpcyB0byBzZWUgd2hhdCBzb3J0IG9mIGNoYW5nZSBpbiBmaWd1cmVzIHdlIGdldCBpZiB0aGlzIGRlZmluaXRpb24gaXMgYWRqdXN0ZWQuIEVxdWFsbHksIGl0IHdvdWxkIGJlIGJlIGluZm9ybWF0aXZlIHRvIHN0YXJ0IGNvbWJpbmluZyB0aGUgbG9jYWxfYXV0aG9yaXR5IGRhdGEgd2l0aCB0aGUgZ3JvdXBzLiBBbHRob3VnaCBub3QgYWxsIGNvbWJpbmF0aW9ucyB3aWxsIGhhdmUgZGF0YSBhdmFpbGFibGUsIGl0IHdpbGwgYmUgaW50ZXJlc3RlZCB0byBjb21wYXJlIHRoZXNlIG5vbmV0aGVsZXNzLiAKCioqRGVmaW5pdGlvbiBBZGp1c3RlZCoqIC0gV2l0aGluIDUgbWludXRlcy4KClRoaXMgY2hhbmdlIGRlZmluZXRlbHkgaGFzIHByZXNpZGVudC4gSW52ZXN0aWdhdGluZyBhIGxpdHRsZSBmdXJ0aGVyLCBpdCBzZWVtcyB0aGF0IGEgY291cGxlIG9mIGdvdmVybm1lbnQgc291cmNlcyByZWZlcmVuY2luZyBhY2Nlc3MgdG8gZ3JlZW4gc3BhY2UgYWN0dWFsbHkgdXNlIGEgNSBtaW51dGUgd2FsayBvciBsZXNzIGFzIHRoZWlyIGRlZmluaXRpb24gW3JlZjFdKGh0dHBzOi8vbmF0aW9uYWxwZXJmb3JtYW5jZS5nb3Yuc2NvdC9hY2Nlc3MtZ3JlZW4tYW5kLWJsdWUtc3BhY2UpICwgW3JlZjJdIChodHRwczovL25hdGlvbmFscGVyZm9ybWFuY2UuZ292LnNjb3QvbWVhc3VyaW5nLXByb2dyZXNzL25hdGlvbmFsLWluZGljYXRvci1wZXJmb3JtYW5jZSkuCgpTbywgd2l0aCB0aGlzIGluIG1pbmQsIGxldCdzIHJ1biB0aGUgYWJvdmUgYW5hbHlzaXMgYWdhaW4gd2l0aCB0aGUgYWRqdXN0ZWQgZGVmaW5pdGlvbjoKCmBgYHtyfQojRmlyc3QsIGNyZWF0aW5nIGEgZGF0YSBmcmFtZSB3aXRoIG1lYW5zIG9mIGFsbCB0aGUgZGlmZmVyZW50IGdyb3VwcyBmcm9tIDIwMTMtMjAxOSBmb3IgdGhlIHdob2xlIG9mIFNjb3RsYW5kLgoKbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMgPC0KYWxsX3dhbGtfZGlzdF9jYXRlZ29yaWVzICU+JSAKICBmaWx0ZXIobG9jYWxfYXV0aG9yaXR5ID09ICJTY290bGFuZCIpICU+JSAKICBncm91cF9ieSh0eXBlLCBjbGFzcykgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gcm91bmQobWVhbihhXzVfbWludXRlX3dhbGtfb3JfbGVzcykpKSAlPiUgCiAgYXJyYW5nZShkZXNjKG1lYW4pKQoKbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfY2F0c18yMDE5IDwtCmFsbF93YWxrX2Rpc3RfY2F0ZWdvcmllcyAlPiUgCiAgZmlsdGVyKGxvY2FsX2F1dGhvcml0eSA9PSAiU2NvdGxhbmQiLAogICAgICAgICB5ZWFyID09ICIyMDE5IikgJT4lIAogIGdyb3VwX2J5KHR5cGUsIGNsYXNzKSAlPiUgCiAgc3VtbWFyaXNlKGFfNV9taW51dGVfd2Fsa19vcl9sZXNzKSAlPiUgCiAgYXJyYW5nZShkZXNjKGFfNV9taW51dGVfd2Fsa19vcl9sZXNzKSkKCm1pbnVzXzVfYWxsX2NhdHNfMjAxOQpgYGAKCmBgYHtyfQptaW51c181X2FsbF9tZWFuc19zY290X2dyb3VwcyAlPiUKICBnZ3Bsb3QoKSArIAogIGFlcyh4ID0gbWVhbiwgeSA9IGNsYXNzLCBmaWxsID0gdHlwZSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfY2F0c18yMDE5ICU+JQogIGdncGxvdCgpICsgCiAgYWVzKHggPSBhXzVfbWludXRlX3dhbGtfb3JfbGVzcywgeSA9IGNsYXNzLCBmaWxsID0gdHlwZSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMgJT4lIAogIGZpbHRlcih0eXBlID09ICJhZ2UiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbWVhbiwgeSA9IGNsYXNzLCBmaWxsID0gY2xhc3MpICsKICBnZW9tX2NvbCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDEwMCwgYnkgPSAxMCkpCmBgYAoKYGBge3J9Cm1pbnVzXzVfYWxsX21lYW5zX3Njb3RfZ3JvdXBzICU+JQogIGZpbHRlcih0eXBlID09ICJldGhuaWNpdHkiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbWVhbiwgeSA9IGNsYXNzLCBmaWxsID0gY2xhc3MpICsKICBnZW9tX2NvbCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDEwMCwgYnkgPSAxMCkpCgpgYGAKCmBgYHtyfQptaW51c181X2FsbF9tZWFuc19zY290X2dyb3VwcyAlPiUKICBmaWx0ZXIodHlwZSA9PSAiZ2VuZGVyIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQoKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMgJT4lIAogIGZpbHRlcih0eXBlID09ICJob3VzZWhvbGRfdHlwZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLCB5ID0gY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMgJT4lCiAgZmlsdGVyKHR5cGUgPT0gInNpbWRfcXVpbnRpbGVzIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQpgYGAKCmBgYHtyfQptaW51c181X2FsbF9tZWFuc19zY290X2dyb3VwcyAlPiUgCiAgZmlsdGVyKHR5cGUgPT0gInR5cGVfb2ZfdGVudXJlIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQoKYGBgCgpgYGB7cn0KbWludXNfNV9hbGxfbWVhbnNfc2NvdF9ncm91cHMgJT4lCiAgZmlsdGVyKHR5cGUgPT0gInVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IG1lYW4sIHkgPSBjbGFzcywgZmlsbCA9IGNsYXNzKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMCwgdG8gPSAxMDAsIGJ5ID0gMTApKQpgYGAKCioqQSBxdWljayBub3RlOiBBbW9uZyB0aGUgbmF0aW9uYWwgcGVyZm9ybWFuY2UgZG9jdW1lbnRhdGlvbiwgdGhlcmUgYXJlIHNvbWUgbW9yZSBleGNlbGxlbnQgZGVmaW5pdGlvbnMgYW5kIGNyaXRlcmlhIGZvciBjaGFuZ2Ugbm90ZWQ6KioKCipEZWZpbml0aW9uczoqCgpBZHVsdHMgYXJlIHBlb3BsZSByZXNpZGVudCBpbiBTY290bGFuZCBhZ2VkIG92ZXIgMTYuCgoqR3JlZW4gYW5kIEJsdWUgU3BhY2UgaXMgZGVzY3JpYmVkIGluIHRoZSBTY290dGlzaCBIb3VzZWhvbGQgU3VydmV5IGFzIGNvbXByaXNpbmcg4oCYcHVibGljIGdyZWVuIG9yIG9wZW4gc3BhY2VzIGluIHlvdXIgbG9jYWwgYXJlYSwgZm9yIGV4YW1wbGUgYSBwYXJrLCBjb3VudHJ5c2lkZSwgd29vZCwgcGxheSBhcmVhLCBjYW5hbCBwYXRoLCByaXZlcnNpZGUgb3IgYmVhY2jigJkuKgoKKkNyaXRlcmlhIGZvciBDaGFuZ2U6KgoKQW55IGRpZmZlcmVuY2UgaW4gdGhlIHBlcmNlbnRhZ2Ugd2l0aGluICsvLSAyIHBlcmNlbnRhZ2UgcG9pbnRzIG9mIGxhc3QgeWVhcidzIGZpZ3VyZSBzdWdnZXN0cyB0aGF0IHRoZSBwb3NpdGlvbiBpcyBtb3JlIGxpa2VseSB0byBiZSBtYWludGFpbmluZyB0aGFuIHNob3dpbmcgYW55IGNoYW5nZS4gCkFuIGluY3JlYXNlIG9mIDIgcGVyY2VudGFnZSBwb2ludHMgb3IgbW9yZSBzdWdnZXN0cyB0aGUgcG9zaXRpb24gaXMgaW1wcm92aW5nLgpBIGRlY3JlYXNlIG9mIDIgcGVyY2VudGFnZSBwb2ludHMgb3IgbW9yZSBzdWdnZXN0cyB0aGUgcG9zaXRpb24gaXMgd29yc2VuaW5nLiAKVGhlIHRocmVzaG9sZCBvZiAyIHBlcmNlbnRhZ2UgcG9pbnRzIGNob3NlbiBpcyBiYXNlZCBvbiB0aGUgZGF0YSBjdXJyZW50bHksIGFuZCBtYXkgYmUgcmV2aWV3ZWQgYXMgbW9yZSBkYXRhIHBvaW50cyBiZWNvbWUgYXZhaWxhYmxlCgoqV2l0aCB0aGUgYWJvdmUgKy8tIDIgcGVyY2VudGFnZSBwb2ludCBjcml0ZXJpYSBpbiBtaW5kLCBJIHdvdWxkIHN1Z2dlc3QgdGhhdCB0aGUgc2FtZSBtZWFzdXJlIGNvdWxkIGFsc28gYmUgdXNlZCBhcyBhICpjcml0ZXJpYSBmb3Igc2lnbmlmaWNhbmNlICouIEluIG90aGVyIHdvcmRzLCBpZiB0aGVyZSBpcyBhIGRpZmZlcmVuY2Ugb2YgKy8tIDIgcGVyY2VudGFnZSBwb2ludHMgYmV0d2VlbiBvbmUgZ3JvdXAgYW5kIGFub3RoZXIsIHRoZW4gaXQgaXMgZGVlbWVkIHRoYXQgb25lIGNsYXNzIGluIGEgdHlwZSBpcyBtb3JlIGxpa2VseS9sZXNzIGxpa2VseSB0aGFuIGFub3RoZXIgdG8gaGF2ZSBhY2Nlc3MgdG8gZ3JlZW4vYmx1ZSBzcGFjZS4qCgpMb29raW5nIGF0IGEgbG90IG9mIHRoZXNlIGdyYXBocywgaXQgbG9va3MgbGlrZSBtYW55IG9mIHRoZSBwYXR0ZXJucyB3aXRoaW4gYW5kIGJldHdlZW4gY2F0ZWdvcmllcyBoYXZlIGJlZW4gaW50ZW5zaWZpZWQsIHdoaWxzdCBvdGhlcnMgaGF2ZSBjaGFuZ2VkIHRvIGEgc2lnbmlmaWNhbnQgZGVncmVlLgoKMS4gVGhlIGdhcCBiZXR3ZWVuIHRob3NlIHdobyBoYXZlIGEgbW9ydGdhZ2Uvb3RoZXIgZG9tZXN0aWMgbG9hbiBhbmQgb3RoZXIgdGVudXJlIGdyb3VwcyBoYXMgYmVlbiBtYWludGFpbmVkLiBJbnRlcmVzdGluZ2x5LCB0aGUgU29jaWFsIFJlbnRpbmcgZ3JvdXAgaGFzIGRyb3BwZWQgYmVsb3cgdGhlIGdyb3VwIE90aGVyIFRlbnVyZS4gVGhlIHBlcmNlbnRhZ2UgcG9pbnQgZ2FwIGJldHdlZW4gbW9ydGdhZ2UgYW5kIHNvY2lhbCByZW50aW5nIGdyb3VwIHdhcyBuaW5lIHBvaW50cy4KMi4gVGhlIGdhcCBiZXR3ZWVuIHRoZSB0d28gU0lNRCBncm91cHMgaGFzIHdpZGVuZWQgc2lnbmlmaWNhbnRseS4gSW4gdGhlIDEwIG9yIGxlc3MgYW5hbHlzaXMsIGl0IHdhcyA0IHBlcmNlbnRhZ2UgcG9pbnRzLiBJbiA1IG9yIGxlc3MsIGl0IGlzIDggcG9pbnRzLgozLiBQZW5zaW9uZXJzIG9uY2UgYWdhaW4gbGFnZ2VkIGJlaGluZCBhZHVsdHMgd2l0aCBhbmQgd2l0aG91dCBjaGlsZHJlbi4KNC4gTWFsZXMgb25jZSBhZ2FpbiByZXBvcnQgY2xvc2VyIGFjY2Vzcywgd2l0aCB0aGUgbWFyZ2luIGdyb3dpbmcgb25seSBzbGlnaHRseSBmcm9tIDIgcGVyY2VudGFnZSBwb2ludHMgdG8gMy4KNS4gVGhlIGdhcCBiZXR3ZWVuIDY1LXllYXItb2xkcysgd2FzIG1haW50YWluZWQuIAo2LiBPbmNlIGFnYWluLCB0aGUgaGVhZGxpbmUgZmlndXJlIGlzIHRoYXQgdGhlIGdhcCBpbiBsb2NhbCBhY2Nlc3MgYmV0d2VlbiB3aGl0ZSBhbmQgbm9uLXdoaXRlIGV0aG5pY2l0eSBoYXMgYmVlbiBmdXJ0aGVyIHdpZGVuZWQgd2l0aCBhIGdhcCBvZiAxMyBwZXJjZW50YWdlIHBvaW50cywgdXAgZnJvbSA4LiBUaG9zZSBjbGFzc2VkIGFzIG5vbi13aGl0ZSBldGhuaWNpdHkgaGFkIHRoZSBsb3dlc3QgcGVyY2VudGFnZSBvZiBhbnkgZ3JvdXAgYWRkcmVzc2VkIG92ZXIgdGhlIGxhc3QgNyB5ZWFycyBwZXJpb2QgbG9va2VkIGludG8sIHdpdGggb25seSA1NCUgaGF2aW5nIGFjY2VzcyB0byBncmVlbiBvciBibHVlIHNwYWNlIHdpdGhpbiA1IG1pbnV0ZXMgd2FsayBvZiB0aGVyZSBob3VzZS4gKipUaGlzIHNob3VsZCBiZSBwdXQgaW50byBjb250ZXh0IGJ5IGhpZ2hsaWdodGluZyB0aGUgZGVmaW5pdGlvbiBhZ2FpbioqLgoKR2VuZXJhdGUgbWVhbnMgZm9yIGFsbCB3YWxraW5nIGRpc3RhbmNlcy4KCmBgYHtyfQphbGxfd2Fsa19kaXN0X21lYW5zX3Njb3RfZ3JvdXBzIDwtCmFsbF93YWxrX2Rpc3RfY2F0ZWdvcmllcyAlPiUgCiAgZmlsdGVyKGxvY2FsX2F1dGhvcml0eSA9PSAiU2NvdGxhbmQiKSAlPiUgCiAgZ3JvdXBfYnkodHlwZSwgY2xhc3MpICU+JSAKICBzdW1tYXJpc2UobGVzc182X21lYW4gPSByb3VuZChtZWFuKGFfNV9taW51dGVfd2Fsa19vcl9sZXNzKSksCiAgICAgICAgICAgIGxlc3NfMTFfbWVhbiA9IHJvdW5kKG1lYW4obGVzc190aGFuXzExX21pbnMpKSwKICAgICAgICAgICAgcGx1c18xMV9tZWFuID0gcm91bmQobWVhbihhbl8xMV9taW51dGVfd2Fsa19vcl9tb3JlKSkpICU+JSAKICBhcnJhbmdlKGRlc2MobGVzc182X21lYW4pKQoKYWxsX3dhbGtfZGlzdF9tZWFuc19zY290X2dyb3VwcwpgYGAKCmBgYHtyfQphbGxfd2Fsa19kaXN0X21lYW5zX3Njb3RfZ3JvdXBzICU+JSAKICBmaWx0ZXIodHlwZSA9PSAidXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24iKQpgYGAKCkFub3RoZXIgc3RyaWtpbmcgaW5zaWdodCBmcm9tIHRoZSBjaGFuZ2UgaW4gZGVmaW5pdGlvbiBpcyB0aGUgc2lnbmlmaWNhbnQgY2hhbmdlIGluIHRoZSB1cmJhbi9ydXJhbCBzcGxpdC4gSW4gdGhlIGxlc3MgdGhhbiAxMSBtZWFuLCB3ZSBoYWQgb25seSBhIHNsaWdodCAxIHBvaW50IGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGdyb3Vwcy4gWWV0LCBvbmNlIHdlIGxvb2sgYXQgNSBtaW5zIG9mIGxlc3MsIHdlIHNlZSB0aGUgZ2FwIGluY3JlYXNlIHRvIDEyIHBlcmNlbnRhZ2UgcG9pbnRzIGluIGZhdm9yIG9mIHRob3NlIGluIGEgcnVyYWwgc2V0dGluZy4gCgoqKkl0IHdvdWxkIGJlIGludGVyZXN0aW5nIHRvIGRvdWJsZS1jaGVjayB3aGF0IHRoZSBkZWZpbml0aW9uIHVzZWQgaXMgZm9yIHJ1cmFsL3VyYmFuIGluIHRoZSBzdXJ2ZXkgb3Igd2hldGhlciB0aGlzIGlzIG9uY2UgYWdhaW4ganVzdCBhIHN1YmplY3RpdmUgcmVzcG9uc2UqKi4KCioqTG9va3MgbGlrZSB0aGVyZSBpcyBhIGdvb2Qgc291cmNlIGZvciB0aGlzIGNyZWF0ZWQgYW5kIHB1Ymxpc2hlZCBpbiAyMDE2IFtyZWYzXShodHRwczovL3d3dy5nb3Yuc2NvdC9wdWJsaWNhdGlvbnMvc2NvdHRpc2gtZ292ZXJubWVudC11cmJhbi1ydXJhbC1jbGFzc2lmaWNhdGlvbi0yMDE2L3BhZ2VzLzIvKS4gSSB0aGluayB0aGF0IGl0IGlzIHRoZSAyLWZvbGQgY2xhc3NpZmljYXRpb24gY3VycmVudGx5IGJlaW5nIHVzZWQsIFRoaXMgc3RhdGVzIHRoZSB0aGUgcnVyYWwgY2xhc3NpZmljYXRpb24gc3RhcnRzIHdpdGggIkFyZWFzIHdpdGggYSBwb3B1bGF0aW9uIG9mIGxlc3MgdGhhbiAzLDAwMCBwZW9wbGUsIGFuZCB3aXRoaW4gYSBkcml2ZSB0aW1lIG9mIDMwIG1pbnV0ZXMgdG8gYSBTZXR0bGVtZW50IG9mIDEwLDAwMCBvciBtb3JlIi4gCgpOb3csIGxldCdzIGhhdmUgYSBsb29rIGF0IHJlZ2lvbmFsIGZpZ3VyZXMgYWdhaW4sIHRoaXMgdGltZSBmb3IgbGVzcyB0aGFuIDUgbWludXRlcyB3YWxrOgoKYGBge3J9CmxvY2FsX21lYW5zICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBsZXNzXzZfbWVhbiwgeSA9IGxvY2FsX2F1dGhvcml0eSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMTAwLCBieSA9IDEwKSkKYGBgCmBgYHtyfQojQ291bGQgZG8gc29tZSBzb3J0IG9mIHBsdXMvbWludXMgdmlzdWFsaXphdGlvbiBiYXNlZCBvbiBTY290bGFuZCBmb3IgdGhlc2UgdHlwZXMgb2YgZ3JhcGhzLgpsb2NhbF9tZWFucyAlPiUgCiAgYXJyYW5nZShkZXNjKGxlc3NfNl9tZWFuKSkKYGBgCgoKCjMuIEFyZSB0aGVyZSBiaWcgZGlmZmVyZW5jZXMgaW4gaG93IGZhciBwZW9wbGUgaGF2ZSB0byB3YWxrIHRvIGFjY2VzcyB0aGVpciBncmVlbiBzcGFjZT8KCipJcyB0aGUgZGF0YSBvbiB0aGUgb3ZlcmFsbCBzYW1wbGUgdmVyeSBza2V3ZWQgdG93YXJkcyBvbmUgb3V0IG9mIHRoZSB0aHJlZSBjYXRlZ29yaWVzIG9yIGlzIGl0IHJlbGF0aXZlbHkgZXZlbmx5IGRpc3BlcnNlZCBhbW9uZ3N0IHNtYWxsLCBtZWRpdW0gYW5kIGxvbmcgd2Fsa3MgdG8gZ3JlZW4gc3BhY2VzLioKCipBcmUgc2ltaWxhciBza2V3cyByZXBsaWNhdGVkIGFjcm9zcyBkaWZmZXJlbnQgcmVnaW9ucyBvciBhcmUgdGhleSBjb25zaXN0ZW50IHdpdGggdGhlIG5hdGlvbmFsIGF2ZXJhZ2UuKgoKCkJhY2sgdG8gdGhlIGdyYXBocyB0aGF0IHdlIHdhbnQgdG8gaGF2ZSB0byBpbGx1c3RyYXRlIGFuZCB0ZWxsIHRoZSBzdG9yaWVzIHRoYXQgd2UndmUgZm91bmQuIExldCdzIHN0YXJ0IHdpdGggdGhlIFNjb3RsYW5kIG1lYW5zIGFzIHRoZSB6ZXJvIHBvaW50IGZvciB0aGUgbGVzcyB0aGFuIDUgYW5kLCBtYXliZSwgbGVzcyB0aGF0IDEwIHBlcmNlbnRhZ2VzLiBMZXQncyBwdXQgYSBob3ZlciBvbiB0aGlzIG9uZSBhcyB3ZWxsLiAKCmBgYHtyfQpsb2NhbF9tZWFuc19wbHVzX21pbnVzX3Njb3QgPC0KbG9jYWxfbWVhbnMgJT4lIAogIG11dGF0ZShwbF9taW5fbGVzc182ID0gbGVzc182X21lYW4gLSBsZXNzXzZfbWVhbltsb2NhbF9hdXRob3JpdHkgPT0gIlNjb3RsYW5kIl0sCiAgICAgICAgIHBsX21pbl9sZXNzXzExID0gbGVzc18xMV9tZWFuIC0gbGVzc18xMV9tZWFuW2xvY2FsX2F1dGhvcml0eSA9PSAiU2NvdGxhbmQiXSwKICAgICAgICAgcGxfbWluX3BsdXNfMTEgPSBwbHVzXzExX21lYW4gLSBwbHVzXzExX21lYW5bbG9jYWxfYXV0aG9yaXR5ID09ICJTY290bGFuZCJdLAogICAgICAgICBhYm92ZV9iZWxvd19sZXNzXzYgPSBpZl9lbHNlKHBsX21pbl9sZXNzXzYgPCAwLCAiYmVsb3ciLCAiYWJvdmUiKSkKYGBgCgoKYGBge3J9CmxvY2FsX21lYW5zX3BsdXNfbWludXNfc2NvdCA8LQogbG9jYWxfbWVhbnNfcGx1c19taW51c19zY290ICU+JSAKICBtdXRhdGUobG9jYWxfYXV0aG9yaXR5ID0gZmN0X3Jlb3JkZXIobG9jYWxfYXV0aG9yaXR5LCBwbF9taW5fbGVzc182KSkKCiNDb3VsZCB3ZSBkbyBhIGNoZWVreSBiaXQgb2Ygbm9ybWFsaXphdGlvbiBoZXJlPyBMaWtlIHRoZXkgZG8gaW4gdGhlIGV4YW1wbGUuIApwbHVzX21pbnVzX3Bsb3QgPC0KbG9jYWxfbWVhbnNfcGx1c19taW51c19zY290ICU+JQogIGdncGxvdChhZXMoeCA9IGxvY2FsX2F1dGhvcml0eSwgeSA9IHBsX21pbl9sZXNzXzYsIGxhYmVsID0gbG9jYWxfYXV0aG9yaXR5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBhZXMoZmlsbCA9IGFib3ZlX2JlbG93X2xlc3NfNiksIHdpZHRoID0gLjUpICsKICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIk1lYW4gUGVyY2VudGFnZSIsCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQWJvdmUgU2NvdGxhbmQiLCAiQmVsb3cgU2NvdGxhbmQiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJhYm92ZSIgPSAiIzAwYmEzOCIsICJiZWxvdyI9ICIjZjg3NjZkIikpICsKICBsYWJzKHRpdGxlID0gIlBlcmNlbnRhZ2Ugb2YgUG9wdWxhdGlvbiBXaXRoaW4gYSA1LW1pbnV0ZSBXYWxrIG9mIEdyZWVuIFNwYWNlIiwKICAgICAgICAgIHN1YnRpdGxlID0gIk1lYW4gZmlndXJlcyBiZXR3ZWVuIDIwMTMgLSAyMDE5IikgKwogIGNvb3JkX2ZsaXAoKQoKcGx1c19taW51c19wbG90CmBgYAoKYGBge3J9CmdncGxvdGx5KHBsdXNfbWludXNfcGxvdCkKYGBgCgoKCmBgYHtyfQpsb2NhbF9tZWFucwpgYGAKCgpgYGB7cn0KI1RoZXNlIGFyZSBsYXJnZXIgam9pbnQgYm9hcmRzIGZvciBlbGVjdG9yYWwgcmVnaXN0cmF0aW9uIGFuZCB0aGUgcHVycG9zZXMgb2YgcHJvcGVydHkgdmFsdWF0aW9uIGZvciBhc3Nlc3NpbmcgY291bmNpbCB0YXggYW5kIHJhdGVzLiBTZWVtcyBzdWl0YWJsZSBpZiB3ZSdyZSBsb29raW5nIGF0IHRlbnVyZSB0eXBlcy4gCgpyZWdpb25zX2FkZGVkX2FsbF93YWxrcyA8LSAKYWxsX3dhbGtfZGlzdF9jYXRlZ29yaWVzICU+JQogIG11dGF0ZShlbGVjdG9yYWxfcmVnaW9uID0gY2FzZV93aGVuKGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkVhc3QgQXlyc2hpcmUiLCAiTm9ydGggQXlyc2hpcmUiLCAiU291dGggQXlyc2hpcmUiKSB+ICJBeXJzaGlyZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiU2NvdHRpc2ggQm9yZGVycyIpIH4gIkJvcmRlcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkNsYWNrbWFubmFuc2hpcmUiLCAiRmFsa2lyayIsICJTdGlybGluZyIpIH4gIkNlbnRyYWwgU2NvdGxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkR1bWZyaWVzIGFuZCBHYWxsb3dheSIpIH4gIkR1bWZyaWVzIGFuZCBHYWxsb3dheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiQXJneWxsIGFuZCBCdXRlIiwgIkVhc3QgRHVuYmFydG9uc2hpcmUiLCAiV2VzdCBEdW5iYXJ0b25zaGlyZSIpIH4gIkR1bmJhcnRvbnNoaXJlIGFuZCBBcmd5bGwgJiBCdXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbF9hdXRob3JpdHkgJWluJSBjKCJGaWZlIikgfiAiRmlmZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiQWJlcmRlZW4gQ2l0eSIsICJBYmVyZGVlbnNoaXJlIiwgIk1vcmF5IikgfiAiR3JhbXBpYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkdsYXNnb3cgQ2l0eSIpIH4gIkdsYXNnb3ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkhpZ2hsYW5kIiwgIk5hIGgtRWlsZWFuYW4gU2lhciIpIH4gIkhpZ2hsYW5kcyBhbmQgV2VzdGVybiBJc2xlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiTm9ydGggTGFuYXJrc2hpcmUiLCAiU291dGggTGFuYXJrc2hpcmUiKSB+ICJMYW5hcmtzaGlyZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiRWFzdCBMb3RoaWFuIiwgIkNpdHkgb2YgRWRpbmJ1cmdoIiwgIk1pZGxvdGhpYW4iLCAiV2VzdCBMb3RoaWFuIikgfiAiTG90aGlhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfYXV0aG9yaXR5ICVpbiUgYygiT3JrbmV5IElzbGFuZHMiLCAiU2hldGxhbmQgSXNsYW5kcyIpIH4gIk9ya25leSBhbmQgU2hldGxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsX2F1dGhvcml0eSAlaW4lIGMoIkVhc3QgUmVuZnJld3NoaXJlIiwgIkludmVyY2x5ZGUiLCAiUmVuZnJld3NoaXJlIikgfiAiUmVuZnJld3NoaXJlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbF9hdXRob3JpdHkgJWluJSBjKCJTY290bGFuZCIpIH4gIlNjb3RsYW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbF9hdXRob3JpdHkgJWluJSBjKCJBbmd1cyIsICJEdW5kZWUgQ2l0eSIsICJQZXJ0aCBhbmQgS2lucm9zcyIpIH4gIlRheXNpZGUiCiAgKQogICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKYGBgCgpgYGB7cn0KbG9jYWxfbWVhbnNfcGx1c19taW51c19zY290ICU+JSAKICBncm91cF9ieSgpCmBgYAoKCk5vdyB0byBkZWNpZGUgZXhhY3RseSB3aGF0IHRvIGRvIHdpdGggdGVuZGVyIGNvbnNpZGVyaW5nIHdoYXQgd2UndmUganVzdCBhZGRlZC4gCgpUaGluayBJJ20gZ29pbmcgdG8gZG8gYSByZXBsaWNhdGUgb2YgdGhlIGFib3ZlIGdyYXBoIGJ1dCB0aGlzIHRpbWUgZm9yIHRoZSBlbGVjdG9yYWwgcmVnaW9ucy4KCmBgYHtyfQpyZWdpb25zX2FkZGVkX2FsbF93YWxrcwpgYGAKCgpgYGB7cn0KcmVnaW9uc19hZGRlZF9hbGxfd2Fsa3MgJT4lIAogIGRpc3RpbmN0KHR5cGUpCmBgYAoKCmBgYHtyfQpyZWdpb25zX2Rpc3RhbmNlc19waXZvdF9sb25nIDwtCnJlZ2lvbnNfYWRkZWRfYWxsX3dhbGtzICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobGVzc190aGFuXzExX21pbnMsIGFuXzExX21pbnV0ZV93YWxrX29yX21vcmUsIGFfNV9taW51dGVfd2Fsa19vcl9sZXNzLCB3aXRoaW5fYV82XzEwX21pbnV0ZV93YWxrLCBkb250X2tub3cpLCBuYW1lc190byA9ICJ3YWxraW5nX2Rpc3RhbmNlIiwgdmFsdWVzX3RvID0gInZhbHVlcyIpCmBgYAoKCmBgYHtyfQojVGhpcyBjb3VsZCBiZSBjbGVhbmVkIHVwIHF1aXRlIGEgYml0LCBhbmQgd2UgY291bGQgZXZlbiB0aGluayBhYm91dCBqdXN0IHRha2luZyBncm91cHMgb2YgcGFydGljdWxhciBpbnRlcmVzdC4gUmVtZW1iZXIsIHRoaXMgaXMgZm9yIFNjb3RsYW5kIGFzIGEgd2hvbGUuIAoKcmVnaW9uc19kaXN0YW5jZXNfcGl2b3RfbG9uZyAlPiUgCiAgZmlsdGVyKGxvY2FsX2F1dGhvcml0eSA9PSAiU2NvdGxhbmQiLAogICAgICAgICB0eXBlID09ICJ0eXBlX29mX3RlbnVyZSIsCiAgICAgICAgIHdhbGtpbmdfZGlzdGFuY2UgJWluJSBjKCJhXzVfbWludXRlX3dhbGtfb3JfbGVzcyIsICJ3aXRoaW5fYV82XzEwX21pbnV0ZV93YWxrIiwgImFuXzExX21pbnV0ZV93YWxrX29yX21vcmUiLCAiZG9udF9rbm93IikpICU+JSAKICAKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWVzLCBmaWxsID0gd2Fsa2luZ19kaXN0YW5jZSkpICsKICBnZW9tX2FyZWEoKSArCiAgZmFjZXRfd3JhcCh+IGNsYXNzKQpgYGAKVGhhdCBzZWVtcyBsaWtlIHNvbWV0aGluZyB3ZSBjb3VsZCB1c2UgaWYgYWxsIGVsc2UgZmFpbHMuCgpgYGB7cn0KcmVnaW9uc19kaXN0YW5jZXNfcGl2b3RfbG9uZyAlPiUgCiAgZGlzdGluY3Qod2Fsa2luZ19kaXN0YW5jZSkKYGBgCgoKYGBge3J9CnJlZ2lvbnNfZGlzdGFuY2VzX3Bpdm90X2xvbmcgJT4lIAogIGZpbHRlcihsb2NhbF9hdXRob3JpdHkgIT0gIlNjb3RsYW5kIiwKICAgICAgICAgd2Fsa2luZ19kaXN0YW5jZSA9PSAiYV81X21pbnV0ZV93YWxrX29yX2xlc3MiLAogICAgICAgICB5ZWFyID09ICIyMDE0IikgJT4lIAogIGFycmFuZ2UoZGVzYyh2YWx1ZXMpKQpgYGAKClRoaW5raW5nIG5vdyB0byBsb29rIGludG8gYSBjaXR5IGJ5IGNpdHkgY29tcGFyaXNvbiBvZiBjZXJ0YWluIGFyZWFzLCB3aXRoIHNvbWUgRHVuZGVlIGNlbnRyaWMgc3R1ZmYgaW4gdGhlaXIgYXMgeW91J2QgZXhwZWN0IQoKYGBge3J9CgpgYGAKCg==